package com.yicheng.statistics.actor.analysis

import java.util.Date
import java.util.concurrent.CountDownLatch

import org.joda.time.DateTime

import com.yicheng.statistics.actor.SaveHtaData
import com.yicheng.statistics.common.TimeUtils
import com.yicheng.statistics.repo.RTAModel.BatteryAlarm
import com.yicheng.statistics.repo.model.Data.AlarmInfo

import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.ActorRef
import akka.actor.Props
import com.yicheng.statistics.repo.cassandra.AlarmInfoDb
import scala.util.Failure
import scala.util.Success
import akka.actor.SupervisorStrategy.Stop

/**
 * 电池报警统计
 * 从报警表里取出电池报警的数据，
 * 如果达到预报警速度门限开始记录等到达到时间门限就统计一条预报警信息，
 * 如果达到报警速度门限开始记录等到达到时间门限就统计一条报警信息
 */
class BatteryAlarmActor extends Actor with ActorLogging{
  
  val saveHtaDataActor:ActorRef = context.child("saveHtaData").
    getOrElse(context.actorOf(Props[SaveHtaData], "saveHtaData"))
  
  import scala.concurrent.ExecutionContext.Implicits.global
  def receive: Receive = {
    case (deviceId:String, deviceType:Int, analyseGroupId:Long) =>
      log.info("电池报警统计 deviceId "+deviceId)
      var alarmState:AlarmState = AlarmState(false, None, None, None, None, None, None, None, None, None, None, deviceId, deviceType)
      val alarmInfos: List[AlarmInfo] = List()
      
      getHourData(0, 1, deviceId, deviceType, alarmState, Parser _)
    case Stop =>
      //context.parent ! Stop
      log.info("batteryalarm stop")
      context.actorSelection("/user/daemon") ! BatteryAlarmStop
    case _ => log.info("BatteryAlarm")
  }
  
  def getHourData(start:Int, interval:Int,deviceId:String, deviceType:Int, alarmState:AlarmState, func:(AlarmState, Seq[AlarmInfo]) => AlarmState): Unit = {
    val time = TimeUtils.getStartEndTimeByHour(start, 1)//取开始时间和结束时间(前一天)
    if(start != 0) {
      AlarmInfoDb.list(deviceType, deviceId, time._1.toDate(), time._2.toDate()) onComplete {
        case Success(result) =>
          val r = func(alarmState, result)
          getHourData(start + 1, interval,deviceId, deviceType, r, func)
        case Failure(error) =>
          println("查询数据失败"+error)
      }
    }else{
      
      AlarmInfoDb.list(deviceType, deviceId, time._1.toDate(), time._2.toDate()) onComplete {
        case Success(result) =>
          result
        case Failure(error) =>
          println("查询数据失败"+error)
      }
    }
  }
  
  def Parser(as:AlarmState, alarms:Seq[AlarmInfo]):AlarmState = {
    var alarmState:AlarmState = as//AlarmState(false, None, None, None, None, None, None, None, None, None, None)
    val deviceId = as.deviceId
    val deviceType = as.deviceType
    
    alarms foreach {
      ai =>
        log.info("alarminfo content is "+ai)
        val vehicleData = ai.alarm_detail.get.alarmVehicle.get.vehicleData
        val alarmdata = vehicleData.alarmData
        val allData = vehicleData.overallData
        val posData = vehicleData.posData
        
        if(!alarmState.start){
          alarmState = alarmState.copy(
              start = true, 
              startTime = Some(ai.alarm_time), 
              startLat = posData.get.latitude, 
              startLon = posData.get.longitude, 
              startMileage = Some(allData.get.currentMileage),
              alarmType = ai.alarm_type, 
              alarmLevel = ai.alarm_level)
        }else{
          if( alarmState.alarmType != ai.alarm_type ){
            val batteryAlarm = BatteryAlarm(
                deviceType,
                deviceId,
                alarmState.startTime,
                alarmState.endTime,
                alarmState.startLon,
                alarmState.startLat,
                alarmState.endLon,
                alarmState.endLat,
                alarmState.startMileage,
                alarmState.endMileage,
                DateTime.now.toDate(),
                alarmState.alarmType.get,
                None,
                None,
                alarmState.alarmLevel,
                None,
                None,
                None
                )
            alarmState = alarmState.copy(
                start = true, 
                startTime = Some(ai.alarm_time), 
                startLat = posData.get.latitude, 
                startLon = posData.get.longitude, 
                startMileage = Some(allData.get.currentMileage),
                alarmType = ai.alarm_type, 
                alarmLevel = ai.alarm_level)
            
            saveHtaDataActor ! batteryAlarm
          }
          else{
            alarmState = alarmState.copy(
                endTime = Some(ai.alarm_time), 
                endLat = posData.get.latitude, 
                endLon = posData.get.longitude, 
                endMileage = Some(allData.get.currentMileage))
          }
        }
    }
    alarmState
  }
  
}

case class AlarmState(
    start:Boolean,
    startTime:Option[Date],
    startLat:Option[Double],
    startLon:Option[Double],
    endTime:Option[Date],
    endLat:Option[Double],
    endLon:Option[Double],
    startMileage:Option[Int],
    endMileage:Option[Int],
    alarmType:Option[Int],
    alarmLevel:Option[Int],
    deviceId:String,
    deviceType:Int
    )
case class BatteryAlarmStop()